package com.fastplatform.service;

import com.fastplatform.entity.Role;
import com.fastplatform.entity.RoleMenu;
import com.fastplatform.entity.UserRole;
import com.fastplatform.repository.RoleRepository;
import com.fastplatform.repository.RoleMenuRepository;
import com.fastplatform.repository.UserRoleRepository;
import com.fastplatform.specification.RoleSpecification;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class RoleService {

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private RoleMenuRepository roleMenuRepository;

    @Autowired
    private UserRoleRepository userRoleRepository;

    /**
     * 获取所有角色（使用JPA命名推断）
     */
    public List<Role> getAllRoles() {
        return roleRepository.findByDeletedFalseOrderBySortOrderAsc();
    }

    /**
     * 根据条件获取角色列表（使用JPA Criteria Queries）
     */
    public List<Role> getRoleList(String roleName, String roleCode, Integer status, Integer page, Integer size) {
        return roleRepository.findAll(RoleSpecification.findRolesByConditions(roleName, roleCode, status));
    }

    /**
     * 根据ID获取角色
     */
    public Role getRoleById(Long id) {
        return roleRepository.findById(id).orElse(null);
    }

    /**
     * 创建角色
     */
    @Transactional
    public Role createRole(Role role) {
        // 检查角色编码是否已存在
        if (roleRepository.findByRoleCodeAndDeletedFalse(role.getRoleCode()).isPresent()) {
            throw new RuntimeException("角色编码已存在");
        }
        
        // 检查角色名称是否已存在
        if (roleRepository.findByRoleNameAndDeletedFalse(role.getRoleName()).isPresent()) {
            throw new RuntimeException("角色名称已存在");
        }
        
        role.setCreateTime(LocalDateTime.now());
        role.setUpdateTime(LocalDateTime.now());
        role.setDeleted(false);
        
        return roleRepository.save(role);
    }

    /**
     * 更新角色
     */
    @Transactional
    public Role updateRole(Role role) {
        Optional<Role> existingRoleOpt = roleRepository.findById(role.getId());
        if (existingRoleOpt.isEmpty()) {
            throw new RuntimeException("角色不存在");
        }
        
        Role existingRole = existingRoleOpt.get();
        
        // 检查角色编码是否已被其他角色使用
        Optional<Role> roleWithSameCode = roleRepository.findByRoleCodeAndDeletedFalse(role.getRoleCode());
        if (roleWithSameCode.isPresent() && !roleWithSameCode.get().getId().equals(role.getId())) {
            throw new RuntimeException("角色编码已存在");
        }
        
        // 检查角色名称是否已被其他角色使用
        Optional<Role> roleWithSameName = roleRepository.findByRoleNameAndDeletedFalse(role.getRoleName());
        if (roleWithSameName.isPresent() && !roleWithSameName.get().getId().equals(role.getId())) {
            throw new RuntimeException("角色名称已存在");
        }
        
        // 更新角色信息
        existingRole.setRoleCode(role.getRoleCode());
        existingRole.setRoleName(role.getRoleName());
        existingRole.setDescription(role.getDescription());
        existingRole.setStatus(role.getStatus());
        existingRole.setSortOrder(role.getSortOrder());
        existingRole.setUpdateTime(LocalDateTime.now());
        
        return roleRepository.save(existingRole);
    }

    /**
     * 删除角色
     */
    @Transactional
    public void deleteRole(Long id) {
        Optional<Role> roleOpt = roleRepository.findById(id);
        if (roleOpt.isEmpty()) {
            throw new RuntimeException("角色不存在");
        }
        
        Role role = roleOpt.get();
        
        // 检查是否有用户关联此角色
        List<UserRole> userRoles = userRoleRepository.findByRoleIdAndDeletedFalse(id);
        if (!userRoles.isEmpty()) {
            throw new RuntimeException("该角色下还有用户，无法删除");
        }
        
        // 软删除角色
        role.setDeleted(true);
        role.setUpdateTime(LocalDateTime.now());
        roleRepository.save(role);
        
        // 删除角色菜单关联
        roleMenuRepository.deleteByRoleId(id);
    }

    /**
     * 获取角色的菜单权限（使用JPA命名推断）
     */
    public List<Long> getRoleMenus(Long roleId) {
        List<RoleMenu> roleMenus = roleMenuRepository.findByRoleId(roleId);
        return roleMenus.stream().map(RoleMenu::getMenuId).collect(Collectors.toList());
    }

    /**
     * 分配角色菜单权限
     */
    @Transactional
    public void assignRoleMenus(Long roleId, List<Long> menuIds) {
        // 先删除原有的角色菜单关联
        roleMenuRepository.deleteByRoleId(roleId);
        
        // 添加新的角色菜单关联
        if (menuIds != null && !menuIds.isEmpty()) {
            for (Long menuId : menuIds) {
                RoleMenu roleMenu = new RoleMenu();
                roleMenu.setRoleId(roleId);
                roleMenu.setMenuId(menuId);
                roleMenuRepository.save(roleMenu);
            }
        }
    }
}